package cn.edu.zzuli;

import java.util.concurrent.*;

/**
 * @Date: 2021/3/9 16:10
 * @Author: 绯色下午茶
 * @Description: 学习使用juc线程池
 * <p>
 * 注意，工作中，以下几种获得线程池的方式都不用，而是要自定义线程池
 * newSingleThreadPool，newFixedThreadPool   因为堆积的阻塞任务（阻塞线程长度）Integer.MAX_VALUE会导致内存溢出
 * newCacheThreadPool，newScheduleThreadPool，因为线程可能创建到Integer.MAX_VALUE导致内存溢出
 */

public class MyThreadPoolDemo {
    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().availableProcessors());
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                2L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()//默认的,直接抛异常
//                new ThreadPoolExecutor.CallerRunsPolicy()//回退到调用者，谁调用的回退给谁
//            new ThreadPoolExecutor.DiscardPolicy()//默默丢弃无法处理的任务，不处理，也不抛异常
//                new ThreadPoolExecutor.DiscardOldestPolicy() //抛弃等待最久的任务，然后把当前任务加入队列中并尝试再次提交当前任务
        );
        try {
            //模拟有10个顾客过来办理业务，目前池子里有5个工作人员提供服务
            for (int i = 1; i <= 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "办理业务");
                });
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();//关闭线程池
        }
    }

    public void test(String[] args) {
//        ExecutorService threadPool = Executors.newFixedThreadPool(5);//一个线程池受理5个线程
//        ExecutorService threadPool = Executors.newSingleThreadExecutor();//只有一个线程
        ExecutorService threadPool = Executors.newCachedThreadPool();//一个线程池有N个线程，可以复用之前构建的线程，可扩容
        try {
            //模拟有10个顾客过来办理业务，目前池子里有5个工作人员提供服务
            for (int i = 0; i < 100; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "办理业务");
                });
            }

        } catch (Exception e) {

        } finally {
            threadPool.shutdown();//关闭线程池
        }
    }
}
